package com.linciping.useges.plugin.asyc;

import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.linciping.useges.plugin.bean.File2R;
import com.linciping.useges.plugin.bean.PsiFile2Content;
import com.linciping.useges.plugin.bean.Res2SourceFile;
import com.linciping.useges.plugin.util.ProjectFileUtil;
import com.linciping.useges.plugin.util.Util;
import com.linciping.useges.plugin.writer.ProjectResUesgesWriter;
import org.jetbrains.jps.model.java.JavaSourceRootType;
import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
import org.jetbrains.kotlin.config.SourceKotlinRootType;

import java.util.*;
import java.util.concurrent.ExecutionException;

public class ProjectResUsegesThread extends ResUsegesThread {

    private final List<Module> modules;
    private final Set<JpsModuleSourceRootType<?>> sourceRootTypes;
    private final String modulePackageName;

    public ProjectResUsegesThread(List<Module> modules, Project project, Module targetModule, List<File2R> resRList, String modulePackageName) {
        super(project, targetModule, resRList);
        this.modules = modules;
        this.modulePackageName = modulePackageName;
        sourceRootTypes = new HashSet<>(2);
        sourceRootTypes.add(JavaSourceRootType.SOURCE);
        sourceRootTypes.add(SourceKotlinRootType.INSTANCE);
    }

    @Override
    public void run() {
        try {
            Map<String, List<Res2SourceFile>> map = new HashMap<>();
            for (Module module : modules) {
                String moduleName = ProjectFileUtil.getModuleName(module);
                List<VirtualFile> virtualFileList = ModuleRootManager.getInstance(module).getSourceRoots(sourceRootTypes);
                List<VirtualFile> findModuleFileList = new ArrayList<>();
                for (VirtualFile virtualFile : virtualFileList) {
                    if (!ProjectFileUtil.isBuildSource(moduleName, virtualFile.getPath())) {
                        findModuleFileList.add(virtualFile);
                    }
                }
                if (findModuleFileList.isEmpty()) {
                    continue;
                }
                List<Res2SourceFile> res2SourceFileList = new ArrayList<>();
                for (VirtualFile sourceFile : findModuleFileList) {
                    List<PsiFile2Content> waitFindPsiFileContentList = new ArrayList<>();
                    buildSource(project, sourceFile, res2SourceFileList, waitFindPsiFileContentList);
                }
                map.put(module.getName(), res2SourceFileList);
            }
            final PsiDirectory moduleDirectory = ProjectFileUtil.getModuleDirectory(targetModule);
            if (moduleDirectory == null) return;
            ApplicationManager.getApplication().runWriteAction(() -> {
                CommandProcessor.getInstance().executeCommand(project, new ProjectResUesgesWriter(project, moduleDirectory, map), "ProjectResUesgesWriter", null);
            });
            callFinish();
        } finally {
            callFinish();
        }
    }

    @Override
    protected List<Res2SourceFile> executorFind(List<List<File2R>> file2RPool, List<PsiFile2Content> waitFindPsiFileContentList) throws ExecutionException, InterruptedException {
        return Util.executorFind(file2RPool, waitFindPsiFileContentList, false, modulePackageName);
    }
}
